# intelligent_sop_cms/intelligent_sop_engine.py
from datetime import datetime
from typing import List, Dict, Any
import time


class IntelligentSOPEngine:
    """智能SOP执行引擎"""

    def __init__(self, decision_engine: AIDecisionEngine):
        self.decision_engine = decision_engine
        self.active_sops = {}
        self.execution_monitor = ExecutionMonitor()
        self.adaptive_planner = AdaptivePlanner()

    def execute_autonomous_sop(self, sop_id: str, context: Dict[str, Any]) -> Dict[str, Any]:
        """自主执行SOP"""
        print(f"开始自主执行SOP: {sop_id}")

        # 获取SOP
        sop = self._get_sop(sop_id)
        if not sop:
            return {"status": "error", "message": "SOP未找到"}

        # 自主决策：SOP适应性调整
        adaptation_decision = self.decision_engine.make_autonomous_decision(
            context, DecisionType.WORKFLOW_OPTIMIZATION
        )

        # 调整SOP
        adapted_sop = self.adaptive_planner.adapt_sop(sop, context, adaptation_decision)

        # 执行监控
        execution_id = self.execution_monitor.start_execution(sop_id, context)

        results = []
        current_step = 0

        try:
            for step in adapted_sop["procedures"]:
                current_step = step["step_number"]

                # 自主决策：步骤执行策略
                step_context = {
                    **context,
                    "current_step": current_step,
                    "step_complexity": step.get("complexity", "medium"),
                    "available_resources": context.get("resources", [])
                }

                step_decision = self.decision_engine.make_autonomous_decision(
                    step_context, DecisionType.RESOURCE_ALLOCATION
                )

                # 执行步骤
                step_result = self._execute_step_autonomously(step, step_decision, context)
                results.append(step_result)

                # 实时监控和调整
                if not self._monitor_step_execution(step_result, execution_id):
                    # 如果步骤执行有问题，重新决策
                    recovery_decision = self.decision_engine.make_autonomous_decision(
                        {**context, "step_failure": step_result},
                        DecisionType.EMERGENCY_RESPONSE
                    )

                    if recovery_decision["decision"] == "abort_procedure":
                        print("自主决策：中止流程")
                        break

                # 步骤间延迟（模拟实际操作）
                time.sleep(0.1)

            # 完成执行
            final_result = self.execution_monitor.complete_execution(
                execution_id, "success", results
            )

            return {
                "status": "success",
                "execution_id": execution_id,
                "results": results,
                "adaptations_applied": adaptation_decision,
                "final_result": final_result
            }

        except Exception as e:
            # 异常处理
            self.execution_monitor.complete_execution(execution_id, "failed", results)
            return {
                "status": "error",
                "execution_id": execution_id,
                "error": str(e),
                "failed_step": current_step
            }

    def _execute_step_autonomously(self, step: Dict, decision: Dict, context: Dict) -> Dict[str, Any]:
        """自主执行单个步骤"""
        step_start = datetime.now()

        print(f"执行步骤 {step['step_number']}: {step['description']}")

        # 模拟步骤执行
        # 在实际系统中，这里会连接实际的设备或系统
        execution_success = self._simulate_step_execution(step, decision)

        step_end = datetime.now()
        duration = (step_end - step_start).total_seconds()

        result = {
            "step_number": step["step_number"],
            "description": step["description"],
            "start_time": step_start.isoformat(),
            "end_time": step_end.isoformat(),
            "duration": duration,
            "success": execution_success,
            "decision_used": decision,
            "quality_check": self._perform_quality_check(step) if execution_success else "failed"
        }

        return result

    def _simulate_step_execution(self, step: Dict, decision: Dict) -> bool:
        """模拟步骤执行"""
        # 模拟执行成功率为95%
        import random
        success_rate = 0.95

        # 如果决策置信度低，降低成功率
        if decision.get("confidence", 1.0) < 0.7:
            success_rate = 0.8

        return random.random() < success_rate

    def _perform_quality_check(self, step: Dict) -> str:
        """执行质量检查"""
        # 模拟质量检查
        import random
        checks = ["passed", "passed", "passed", "warning", "passed"]
        return random.choice(checks)

    def _monitor_step_execution(self, step_result: Dict, execution_id: str) -> bool:
        """监控步骤执行"""
        if not step_result["success"]:
            print(f"步骤 {step_result['step_number']} 执行失败")
            self.execution_monitor.record_issue(
                execution_id,
                f"步骤{step_result['step_number']}执行失败",
                "high"
            )
            return False

        if step_result["quality_check"] == "warning":
            print(f"步骤 {step_result['step_number']} 质量检查警告")
            self.execution_monitor.record_issue(
                execution_id,
                f"步骤{step_result['step_number']}质量警告",
                "medium"
            )

        return True

    def _get_sop(self, sop_id: str) -> Dict[str, Any]:
        """获取SOP（模拟）"""
        # 在实际系统中，这里会从数据库获取
        return {
            "sop_id": sop_id,
            "title": "智能生产流程",
            "procedures": [
                {"step_number": 1, "description": "设备初始化检查", "complexity": "low"},
                {"step_number": 2, "description": "材料准备和验证", "complexity": "medium"},
                {"step_number": 3, "description": "核心工艺执行", "complexity": "high"},
                {"step_number": 4, "description": "质量检测", "complexity": "medium"},
                {"step_number": 5, "description": "结果记录和报告", "complexity": "low"}
            ]
        }


class ExecutionMonitor:
    """执行监控器"""

    def __init__(self):
        self.executions = {}
        self.performance_metrics = {}

    def start_execution(self, sop_id: str, context: Dict) -> str:
        """开始执行监控"""
        execution_id = f"EXEC-{datetime.now().strftime('%Y%m%d%H%M%S')}"

        self.executions[execution_id] = {
            "sop_id": sop_id,
            "start_time": datetime.now(),
            "context": context,
            "status": "running",
            "steps_completed": 0,
            "issues": []
        }

        return execution_id

    def record_issue(self, execution_id: str, issue: str, severity: str):
        """记录执行问题"""
        if execution_id in self.executions:
            self.executions[execution_id]["issues"].append({
                "timestamp": datetime.now(),
                "issue": issue,
                "severity": severity
            })

    def complete_execution(self, execution_id: str, status: str, results: List[Dict]) -> Dict[str, Any]:
        """完成执行记录"""
        if execution_id in self.executions:
            execution = self.executions[execution_id]
            execution["end_time"] = datetime.now()
            execution["status"] = status
            execution["results"] = results

            duration = (execution["end_time"] - execution["start_time"]).total_seconds()

            # 计算性能指标
            performance = {
                "total_duration": duration,
                "steps_completed": len([r for r in results if r["success"]]),
                "total_steps": len(results),
                "success_rate": len([r for r in results if r["success"]]) / len(results),
                "issues_count": len(execution["issues"])
            }

            self.performance_metrics[execution_id] = performance
            return performance

        return {}


class AdaptivePlanner:
    """自适应规划器"""

    def adapt_sop(self, sop: Dict, context: Dict, decision: Dict) -> Dict:
        """自适应调整SOP"""
        adapted_sop = sop.copy()

        # 基于决策调整SOP
        if decision["decision"] == "optimize_for_speed":
            # 优化速度：合并简单步骤
            adapted_sop["procedures"] = self._merge_simple_steps(sop["procedures"])
        elif decision["decision"] == "enhance_safety":
            # 增强安全：添加安全检查步骤
            adapted_sop["procedures"] = self._add_safety_checks(sop["procedures"])
        elif decision["decision"] == "simplify_for_training":
            # 培训简化：添加详细说明
            adapted_sop["procedures"] = self._add_training_details(sop["procedures"])

        adapted_sop["adaptation_reason"] = decision
        return adapted_sop

    def _merge_simple_steps(self, procedures: List[Dict]) -> List[Dict]:
        """合并简单步骤"""
        # 简化实现
        return procedures

    def _add_safety_checks(self, procedures: List[Dict]) -> List[Dict]:
        """添加安全检查"""
        adapted = []
        for procedure in procedures:
            adapted.append(procedure)
            if procedure.get("complexity") == "high":
                # 在高复杂度步骤后添加安全检查
                safety_step = {
                    "step_number": procedure["step_number"] + 0.5,
                    "description": f"安全检查：{procedure['description']}",
                    "complexity": "low",
                    "is_safety_check": True
                }
                adapted.append(safety_step)
        return sorted(adapted, key=lambda x: x["step_number"])

    def _add_training_details(self, procedures: List[Dict]) -> List[Dict]:
        """添加培训详情"""
        adapted = []
        for procedure in procedures:
            detailed_procedure = procedure.copy()
            detailed_procedure["training_notes"] = f"重点注意：{procedure['description']}"
            adapted.append(detailed_procedure)
        return adapted